Namespace.Use("Application.Sensor.Rectifier", function(ns) {
    //
    //  Imports.
    //
    var MinimumHeap = Namespace.Import("Base.Structure.MinimumHeap");

    //
    //  Classes.
    //
    var LinearTimeRectifier = Polymorphic.Create(
        [],
        function() {
            var last_get = null;
            var pending = new MinimumHeap(function(_d1, _d2) {
                return _d1.Time - _d2.Time;
            });

            //
            //  Private methods.
            //
            function reset() {
                pending.Clear();
            }

            function put(timestamp, data) {
                if (last_get !== null && timestamp < last_get) {
                    console.warn("[Rectifier/LinearTime] Input data dropped.");
                    return;
                }
                pending.Push({
                    "Time": timestamp,
                    "Data": data
                });
            }

            function get() {
                //  Get the samples.
                var rs_ts = [], rs_data = [];
                while(pending.GetLength() != 0) {
                    var item = pending.Pop();
                    rs_ts.push(item.Time);
                    rs_data.push(item.Data);
                    last_get = item.Time;
                }

                return [rs_ts, rs_data];
            }

            //
            //  Public methods.
            //
            this.Put = Polymorphic.Create(
                [Number, Object],
                function(timestamp, data) {
                    put(timestamp, data);
                }
            );
            this.Get = function() {
                return get();
            };
            this.Reset = function() {
                reset();
            };
        }
    );

    //  Export public APIs / classes.
    Namespace.Export(ns, "LinearTimeRectifier", LinearTimeRectifier);
});
